﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LPPA.Facturacion.BizEntities;
using LPPA.Facturacion.DataAccess;
using LPPA.Facturacion.Services.Logger;

namespace LPPA.Facturacion.BusinessLayer
{
    public class TitularService
    {
        #region Private Methods
        /// <summary>
        /// Crear Titular a partir de un TitularBIZ
        /// </summary>
        /// <param name="pTitularBiz"></param>
        /// <returns></returns>
        private static Titular BIZToNewEntity(TitularBIZ pTitularBiz)
        {
            try
            {
                return new Titular()
            {
                DireccionFC = pTitularBiz.Direccion,
                FechaNacimiento = pTitularBiz.FechaNacimiento,
                Mail = pTitularBiz.Mail,
                Nombre = pTitularBiz.Nombre,
                Web = pTitularBiz.Web,
                Telefono = pTitularBiz.Telefono,
                Cod_Titular = pTitularBiz.CodigoTitular
            };
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al convertir un TitularBIZ en un nuevo Titular.", ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// Convierte un TitularBIZ en un Titular
        /// </summary>
        /// <param name="TitularBIZ"></param>
        /// <param name="TitularEntity"></param>
        /// <returns></returns>
        private static Titular BIZToEntity(TitularBIZ TitularBIZ, Titular TitularEntity)
        {
            try
            {
                TitularEntity.DireccionFC = TitularBIZ.Direccion;
                TitularEntity.FechaNacimiento = TitularBIZ.FechaNacimiento;
                TitularEntity.Mail = TitularBIZ.Mail;
                TitularEntity.Nombre = TitularBIZ.Nombre;
                TitularEntity.Web = TitularBIZ.Web;
                TitularEntity.Telefono = TitularBIZ.Telefono;
                TitularEntity.Cod_Titular = TitularBIZ.CodigoTitular;

                return TitularEntity;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al convertir un TitularBIZ en un Titular.", ex.StackTrace);
                throw;
            }

        }

        /// <summary>
        /// Conviernte un Titular en un TitularBIZ
        /// </summary>
        /// <param name="titular"></param>
        /// <returns></returns>
        private static TitularBIZ ToBIZ(Titular titular)
        {
            try
            {
                return new TitularBIZ()
            {
                CodigoTitular = titular.Cod_Titular,
                Direccion = titular.DireccionFC,
                FechaNacimiento = (titular.FechaNacimiento.HasValue) ? titular.FechaNacimiento : null,
                Mail = titular.Mail,
                Nombre = titular.Nombre,
                Telefono = titular.Telefono,
                Web = titular.Web
            };
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al convertir un Titular en un TitularBIZ.", ex.StackTrace);
                throw;
            }
        }
        #endregion

        #region CRUD Operations

        /// <summary>
        /// Crear Titular
        /// </summary>
        /// <param name="TitularBIZ"></param>
        /// <returns></returns>
        public int Insert(TitularBIZ TitularBIZ)
        {
            try
            {
                using (DataAccess.dcEdenorteDataContext context = new DataAccess.dcEdenorteDataContext())
                {
                    var titularToInsert = BIZToNewEntity(TitularBIZ);
                    context.Titulars.InsertOnSubmit(titularToInsert);

                    context.SubmitChanges();
                    //ToDo: Ver de retornar el ID.
                    return titularToInsert.Cod_Titular;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al intentar insertar un nuevo Titular.", ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// Actualizar Titular
        /// </summary>
        /// <param name="TitularBIZ"></param>
        public void Update(TitularBIZ TitularBIZ)
        {
            try
            {
                using (DataAccess.dcEdenorteDataContext context = new DataAccess.dcEdenorteDataContext())
                {

                    var titular = (from t in context.Titulars
                                   where t.Cod_Titular == TitularBIZ.CodigoTitular
                                   select t).SingleOrDefault();

                    BIZToEntity(TitularBIZ, titular);

                    context.SubmitChanges();
                    //ToDo: Ver de retornar el ID.
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al actualizar un Titular.", ex.StackTrace);
                throw;
            }
        }

        #endregion

        #region Gets

        /// <summary>
        /// Obtiene una lista de todos los Titulares existentes.
        /// </summary>
        /// <returns></returns>
        public List<TitularBIZ> GetAll()
        {
            try
            {
                List<TitularBIZ> listTitulares = new List<TitularBIZ>();

                using (DataAccess.dcEdenorteDataContext context = new DataAccess.dcEdenorteDataContext())
                {
                    var titularesCollection =
                        from t in context.Titulars
                        select t;

                    foreach (var titular in titularesCollection)
                    {
                        listTitulares.Add(ToBIZ(titular));
                    }

                }
                return listTitulares;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al obtener todos los Titulares.", ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// Obtiene un Titular según su Id.
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public TitularBIZ GetById(int Id)
        {
            try
            {
                using (DataAccess.dcEdenorteDataContext context = new DataAccess.dcEdenorteDataContext())
                {
                    var titularesCollection =
                        from t in context.Titulars
                        where t.Cod_Titular == Id
                        select t;

                    return ToBIZ(titularesCollection.SingleOrDefault());
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al obtener un Titular por su Id.", ex.StackTrace);
                throw;
            }
        }

        /// <summary>
        /// Obtiene una lista de Titulares según el nombre.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<TitularBIZ> GetByName(string name)
        {
            try
            {
                List<TitularBIZ> _listToReturn = new List<TitularBIZ>();

                using (DataAccess.dcEdenorteDataContext context = new DataAccess.dcEdenorteDataContext())
                {
                    var titularesCollection =
                        from t in context.Titulars
                        where t.Nombre.ToLower().Contains(name)
                        select t;

                    foreach (var item in titularesCollection)
                    {
                        _listToReturn.Add(ToBIZ(item));
                    }

                    return _listToReturn;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Error al obtener un Titular por su Nombre.", ex.StackTrace);
                throw;
            }
        }

        #endregion
    }
}
